// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: wsfuyibing <682805@qq.com>
// Date: 2024-08-02

package gen_model

import (
	"context"
	"gitee.com/go-libs/console"
	"gitee.com/go-libs/db-xorm/db/commands"
	"gitee.com/go-libs/db-xorm/db/commands/base"
)

const (
	Name              = base.CommandNameModel
	Description       = "Generate model files"
	DefaultTargetPath = "app/http/models"
)

// Provider
// is a component used to generate model files.
type Provider struct {
	common  *commands.Common
	command *console.Command
}

// Before
// is a before runner hook handler for command.
func (o *Provider) Before(_ context.Context, _ *console.Container, command *console.Command) (err error) {
	// log.Config().SetLevel("error")

	// Read and validate
	// options value.
	//
	//   --base-dir
	//   --dsn
	for _, fn := range []func() error{
		func() error { return o.common.ReadBaseDir(command, base.OptBaseDir, base.OptBaseDirDefault) },
		func() error { return o.common.BuildModule(command) },
		func() error { return o.common.ReadDsn(command, base.OptDsn) },
		func() error { return o.common.ReadExport(command, base.OptExport) },
		func() error { return o.common.ReadOverride(command, base.OptOverride) },
		func() error { return o.common.ReadPrefix(command, base.OptPrefix) },
		func() error { return o.common.ReadTargetPath(command, base.OptTargetPath, DefaultTargetPath) },
		func() error { return o.common.RegisterDatabase() },
	} {
		if err = fn(); err != nil {
			break
		}
	}
	return
}

// Run
// is a runner hook handler for command.
func (o *Provider) Run(ctx context.Context, container *console.Container, command *console.Command) (err error) {
	var tables []*base.Table

	// Return error
	// if tables list failed.
	if tables, err = o.common.ListTable(ctx, command, true); err != nil {
		return
	}

	// Iterate
	// tables and generate it.
	for _, table := range tables {
		if err = (&Generator{
			Common:    o.common,
			Command:   command,
			Container: container,
			Table:     table,
		}).Run(ctx); err != nil {
			break
		}
	}
	return
}
